﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Windows.Forms;

namespace zykControl
{
    public partial class FrmUIBindingEditer
    {
        public FrmUIBindingEditer()
        {
            InitializeComponent();
        }

        private bool mIsOK;
        private DataFieldItem[]? mValues;
        private Control? mControl;

        public static DataFieldItem[]? ShowA(ITypeDescriptorContext context, IServiceProvider _, object? value)
        {
            var dI = new FrmUIBindingEditer()
            {
                mControl = (Control)context.Instance!,
                mValues = (DataFieldItem[]?)value
            };
            dI.Text = "DataField绑定编辑 - 当前控件: " + dI.mControl.GetType().Name + " (" + dI.mControl.Name + ")";
            dI.RefreshListView();
            dI.RefreshDataGridView();
            dI.mIsOK = false;
            dI.ShowDialog();
            return dI.mIsOK ? dI.mValues : null;
        }

        private void RefreshDataGridView()
        {
            if (mValues == null) return;

            var dList = new List<CFrmUIBindingEditerItem>();
            var dPropertys = mControl!.GetType().GetProperties(System.Reflection.BindingFlags.Instance | System.Reflection.BindingFlags.Public);
            foreach (var dProp in dPropertys)
            {
                if (dProp.CanRead == false || dProp.CanWrite == false)
                    continue;
                bool dIsBinding = false;
                var dAttrs = dProp.GetCustomAttributes(typeof(BindableAttribute), true);
                if (dAttrs is not null && dAttrs.Length > 0)
                {
                    if (((BindableAttribute)dAttrs[0]).Bindable)
                        dIsBinding = true;
                    else
                        continue;
                }

                if (dIsBinding == false)
                {
                    dAttrs = dProp.PropertyType.GetCustomAttributes(typeof(ListBindableAttribute), true);
                    if (dAttrs is not null && dAttrs.Length > 0)
                    {
                        if (((ListBindableAttribute)dAttrs[0]).ListBindable)
                            dIsBinding = true;
                        else
                            continue;
                    }
                    // dAttrs = dProp.GetCustomAttributes(GetType(BrowsableAttribute), True)
                    // If dAttrs IsNot Nothing AndAlso dAttrs.Length > 0 Then
                    // If DirectCast(dAttrs(0), BrowsableAttribute).Browsable = False Then Continue For
                    // End If
                }

                var dItem = new CFrmUIBindingEditerItem()
                {
                    FieldName = "",
                    PropertyName = dProp.Name,
                    UpdateMode = "",
                    FormatString = "",
                    NullText = ""
                };
                dList.Add(dItem);
            }

            dList.Sort((item1, item2) => { if (string.Compare(item1.PropertyName, item2.PropertyName, false) > 0) { return 1; } else if (string.Compare(item1.PropertyName, item2.PropertyName, false) < 0) { return -1; } else { return 0; } });
            var dBindingList = new BindingList<CFrmUIBindingEditerItem>(dList);
            foreach (var dItem in mValues)
            {
                var dListItem = dBindingList.FirstOrDefault(item => (item.PropertyName ?? "") == (dItem.PropertyName ?? ""));
                if (dListItem is not null)
                {
                    dListItem.FieldName = dItem.DataField;
                    dListItem.FormatString = dItem.FormatString;
                    dListItem.NullText = dItem.NullText;
                    dListItem.UpdateMode = new[] { "标准", "实时", "不更新" }[(int)dItem.UpdateMode];
                }
            }

            dgvList.DataSource = dBindingList;
        }

        private void BtnCancel_Click(object sender, EventArgs e)
        {
            Close();
        }

        private void RefreshListView()
        {
            if (mValues == null) return;

            lsvList.Items.Clear();
            foreach (DataFieldItem dItem in mValues)
            {
                var dListItem = lsvList.Items.Add(dItem.PropertyName);
                dListItem.SubItems.Add(dItem.DataField);
                string dInfo = new[] { "标准", "实时", "不更新" }[(int)dItem.UpdateMode];
                if (!string.IsNullOrEmpty(dItem.FormatString))
                {
                    dInfo += " (" + dItem.FormatString + ")";
                }

                if (!string.IsNullOrEmpty(dItem.NullText))
                {
                    dInfo += " [" + dItem.NullText + "]";
                }

                dListItem.SubItems.Add(dInfo);
            }
        }

        private void RefreshListViewByDataGrid()
        {
            BindingList<CFrmUIBindingEditerItem> dList = (BindingList<CFrmUIBindingEditerItem>)dgvList.DataSource;
            lsvList.Items.Clear();
            foreach (var dItem in dList)
            {
                if (dItem?.FieldName is null || string.IsNullOrEmpty(dItem.FieldName.Trim())) continue;
                var dListItem = lsvList.Items.Add(dItem.PropertyName);
                dListItem.SubItems.Add(dItem.FieldName.Trim());
                string dInfo = string.IsNullOrEmpty(dItem.UpdateMode ?? "") ? "标准" : (dItem.UpdateMode ?? "");
                if (!string.IsNullOrEmpty(dItem.FormatString))
                {
                    dInfo += " (" + dItem.FormatString + ")";
                }

                if (!string.IsNullOrEmpty(dItem.NullText))
                {
                    dInfo += " [" + dItem.NullText + "]";
                }

                dListItem.SubItems.Add(dInfo);
            }
        }

        private void DgvList_CellValueChanged(object sender, DataGridViewCellEventArgs e)
        {
            if (Created == false) return;
            RefreshListViewByDataGrid();
        }

        private void BtnOK_Click(object sender, EventArgs e)
        {
            var dValues = new List<DataFieldItem>();
            BindingList<CFrmUIBindingEditerItem> dList = (BindingList<CFrmUIBindingEditerItem>)dgvList.DataSource;
            foreach (var dItem in dList)
            {
                if (string.IsNullOrEmpty(dItem.FieldName?.Trim())) continue;

                DataSourceUpdateMode dUpdateMode;
                if (dItem.UpdateMode == "不更新")
                {
                    dUpdateMode = DataSourceUpdateMode.Never;
                }
                else if (dItem.UpdateMode == "实时")
                {
                    dUpdateMode = DataSourceUpdateMode.OnPropertyChanged;
                }
                else
                {
                    dUpdateMode = DataSourceUpdateMode.OnValidation;
                }

                var dFieldItem = new DataFieldItem()
                {
                    DataField = dItem.FieldName ?? "",
                    PropertyName = dItem.PropertyName,
                    FormatString = dItem.FormatString ?? "",
                    NullText = dItem.NullText ?? "",
                    UpdateMode = dUpdateMode
                };
                if ((int)dFieldItem.UpdateMode < 0) dFieldItem.UpdateMode = DataSourceUpdateMode.OnValidation;
                dValues.Add(dFieldItem);
            }

            mValues = [.. dValues];
            mIsOK = true;
            Close();
        }

        private void 删除ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (lsvList.SelectedItems is null) return;

            BindingList<CFrmUIBindingEditerItem> dTable = (BindingList<CFrmUIBindingEditerItem>)dgvList.DataSource;
            foreach (ListViewItem dItem in lsvList.SelectedItems)
            {
                var dRow = dTable.FirstOrDefault(item => (item.PropertyName ?? "") == (dItem.Text ?? ""));
                if (dRow == null) continue;

                dRow.FieldName = "";
                dRow.FormatString = "";
                dRow.NullText = "";
                dRow.UpdateMode = "";
            }

            RefreshListViewByDataGrid();
        }

        private void 全部清除ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            if (lsvList.Items.Count == 0)
                return;
            if (MessageBox.Show("确定要全部清除吗?", "DataField绑定编辑", MessageBoxButtons.OKCancel) == DialogResult.Cancel)
                return;
            BindingList<CFrmUIBindingEditerItem> dTable = (BindingList<CFrmUIBindingEditerItem>)dgvList.DataSource;
            foreach (ListViewItem dItem in lsvList.Items)
            {
                var dRow = dTable.FirstOrDefault(item => (item.PropertyName ?? "") == (dItem.Text ?? ""));
                if (dRow == null) continue;

                dRow.FieldName = "";
                dRow.FormatString = "";
                dRow.NullText = "";
                dRow.UpdateMode = "";
            }

            RefreshListViewByDataGrid();
        }

        private void LsvList_DoubleClick(object sender, EventArgs e)
        {
            if (lsvList.SelectedItems.Count == 0)
                return;
            string dText = lsvList.SelectedItems[0].Text;
            foreach (DataGridViewRow dRow in dgvList.Rows)
            {
                CFrmUIBindingEditerItem dItem = (CFrmUIBindingEditerItem)dRow.DataBoundItem;
                if ((dItem.PropertyName ?? "") == (dText ?? ""))
                {
                    dRow.Selected = true;
                    dgvList.CurrentCell = dRow.Cells[0];
                }
            }
        }
    }

    public class CFrmUIBindingEditerItem : INotifyPropertyChanged
    {
        private string mPropertyName = "";
        /// <summary>控件的属性名</summary>
        public string PropertyName
        {
            get
            {
                return mPropertyName;
            }
            set
            {
                mPropertyName = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(PropertyName)));
            }
        }

        private string mFieldName = "";
        /// <summary>模型的属性名</summary>
        public string FieldName
        {
            get
            {
                return mFieldName;
            }
            set
            {
                mFieldName = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(FieldName)));
            }
        }

        private string mUpdateMode = "";

        public string UpdateMode
        {
            get
            {
                return mUpdateMode;
            }
            set
            {
                mUpdateMode = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(UpdateMode)));
            }
        }

        private string mFormatString = "";

        public string FormatString
        {
            get
            {
                return mFormatString;
            }
            set
            {
                mFormatString = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(FormatString)));
            }
        }

        private string mNullText = "";

        public string NullText
        {
            get
            {
                return mNullText;
            }
            set
            {
                mNullText = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(NullText)));
            }
        }

        public event PropertyChangedEventHandler? PropertyChanged;
    }
}